/**
 * @file    pc_comm_server_task.c
 * @brief   请求订阅任务通信服务
 * @details This is the detail description.
 * @author  wang-haoyu
 * @date    2025年7月29日 (created)
 * @version 0.0.2
 * @par Copyright (C):
 *          All Rights Reserved.
 * @par Encoding:
 *          GB2312
 * @par Description        :
 * 1. Hardware Descriptions:
 *      None.
 * 2. Program Architecture:
 *      None.
 * 3. File Usage:
 *      None.
 * 4. Limitations:
 *      None.
 * 5. Else:
 *      None.
 * @par Modification:
 * -# Date          : 2025年7月29日;
 * Revision         : 0.0.1;
 * Author           : wang-haoyu;
 * Contents         : first update
 */
 
/* =============================================================================
 *                                header files
 * ========================================================================== */
#include "pc_comm_server_task.h"
#include "pc_comm_cfg.h"
#include "chassis.h"
#include "battery.h"
#include "user_ipc.h"
#include "env_param.h"
#include "signal_led.h"
#include "multifunction_io.h"
#include "light_bar_box.h"

#define LOG_TAG "pccomm_server_task"
#include "ulog.h"
/* =============================================================================
 *                              macros & constants
 * ========================================================================== */
static McnNode_t pc_poweroff_request_node;
/* =============================================================================
 *                          data structure definitions
 * ========================================================================== */
/**********响应任务结构体初始化************/
static pccomm_ack_task_t s_pccomm_ack_task[] = 
{
	{CHASSIS_INIT_STA ,	pc_comm_single_func_chassis_init_status},
	{CLEAR_ERR_STA	  ,	pc_comm_single_func_clear_error_status},
	{PC_PWR_STA	  	  ,	pc_comm_single_func_pc_pwr_status},
};

/**********请求任务结构体初始化************/
static pccomm_request_task_t s_pccomm_request_task[] =
{
	{CHASSIS_INIT_CODE		,	pc_comm_server_func_chassis_init},
	{CLEAR_ERR_CTRL_CODE	,	pc_comm_server_func_clear_error},
	{PC_PWR_CTRL_CODE		,	pc_comm_server_func_pc_pwr_ctrl},
};

/* =============================================================================
 *                         static variable definitions
 * ========================================================================== */
static int chassis_init_sta = 0;
static bool chassis_init_flag = false;
static bool clear_error_flag = false;
/* =============================================================================
 *                         static function definitions
 * ========================================================================== */

/* =============================================================================
 *                         global function definitions
 * ========================================================================== */
/*
 * 请求订阅任务初始化函数
 *
 * Parameter:
 *   Input:
 *   Output:
 * Returns:
 */
 void pc_comm_server_task_init(void)
{
	pc_poweroff_request_node = mcn_subscribe(MCN_HUB(pc_pwroff_request), RT_NULL, RT_NULL);
}

/*
 * MCU->PC 响应任务轮询函数
 *
 * Parameter:
 *   Input:
 * 		-dev:数据发送驱动
 *   Output:
 * Returns:
 */
void pc_comm_server_ack_task_processing(rt_device_t dev)
{
    for(int i = 0;i<sizeof(s_pccomm_ack_task)/sizeof(s_pccomm_ack_task[0]);i++)
    {
		s_pccomm_ack_task[i].task_handler(dev);
    }
}

/*
 * PC-MCU 请求任务轮询函数函数
 *
 * Parameter:
 *   Input:
 * 		-*obj:通信数据帧句柄
 *   Output:
 * Returns:
 */
void pc_comm_server_request_task_processing(pc_comm_frame_t *obj)
{
    for(int i = 0;i<sizeof(s_pccomm_request_task)/sizeof(s_pccomm_request_task[0]);i++)
    {
        if(obj->head.func_code == s_pccomm_request_task[i].func_code)
            s_pccomm_request_task[i].task_handler(obj->proto_buf,obj->head.data_len);
    }
}

/*****************MCU>>>>>>>>PC*******************/

/*
 * MCU->PC 底盘初始化状态反馈函数
 *
 * Parameter:
 *   Input:
 *   Output:
 * Returns:
 */
void pc_comm_single_func_chassis_init_status(rt_device_t dev)
{
	bool status = false;
	rt_uint16_t crc = 0;
	pb_byte_t send_buf[128] = {0};
	DangkangProtobuf_ChassisInitialization msg = DangkangProtobuf_ChassisInitialization_init_zero;
	
	if(false == chassis_init_flag)
		return;

	send_buf[0] = PC_COMM_HEAD;
	send_buf[1] = CHASSIS_INIT_STA;

	
	pb_ostream_t stream = pb_ostream_from_buffer(&send_buf[3],sizeof(send_buf));


	if(chassis_init_sta != 0)
	{
		msg.state_response = DangkangProtobuf_StateFeedback_SF_FAIL;
		chassis_init_flag = false;
	}
	else
	{
		msg.state_response = DangkangProtobuf_StateFeedback_SF_SUCCESS;
		chassis_init_flag = false;
	}
	
	status = pb_encode(&stream, DangkangProtobuf_ChassisInitialization_fields, &msg);
	if(!status)
		LOG_E("chassis init status info failed: %s\n", PB_GET_ERROR(&stream));
	else
	{
		send_buf[2] = stream.bytes_written;
		send_buf[send_buf[2] + 5] = PC_COMM_TAIL;

		crc = cal_crc16(send_buf, send_buf[2] + 3);
		send_buf[send_buf[2] + 3] = (crc & 0xff);
		send_buf[send_buf[2] + 4] = (crc & 0xff00) >> 8;
		rt_device_write(dev, 0, send_buf, send_buf[2] + 6);
	}
}

/*
 * MCU->PC 清除错误状态反馈函数
 *
 * Parameter:
 *   Input:
 *   Output:
 * Returns:
 */
void pc_comm_single_func_clear_error_status(rt_device_t dev)
{
	bool status = false;
	rt_uint16_t crc = 0;
	pb_byte_t send_buf[128] = {0};
	DangkangProtobuf_ErrorClearControl msg = DangkangProtobuf_ErrorClearControl_init_zero;

	if(true != clear_error_flag)
		return ;
	
	send_buf[0] = PC_COMM_HEAD;
	send_buf[1] = CLEAR_ERR_STA;

	
	pb_ostream_t stream = pb_ostream_from_buffer(&send_buf[3],sizeof(send_buf));
	msg.state_response = DangkangProtobuf_StateFeedback_SF_SUCCESS;
	
	status = pb_encode(&stream, DangkangProtobuf_ErrorClearControl_fields, &msg);
	if(!status)
		LOG_E("clear error status info failed: %s\n", PB_GET_ERROR(&stream));
	else
	{
		send_buf[2] = stream.bytes_written;
		send_buf[send_buf[2] + 5] = PC_COMM_TAIL;

		crc = cal_crc16(send_buf, send_buf[2] + 3);
		send_buf[send_buf[2] + 3] = (crc & 0xff);
		send_buf[send_buf[2] + 4] = (crc & 0xff00) >> 8;
		rt_device_write(dev, 0, send_buf, send_buf[2] + 6);
	}
}

/*
 * MCU->PC PC电源控制函数
 *
 * Parameter:
 *   Input:
 *   Output:
 * Returns:
 */
void pc_comm_single_func_pc_pwr_status(rt_device_t dev)
{
	bool status = false;
	rt_uint16_t crc = 0;
	pb_byte_t send_buf[128] = {0};
	DangkangProtobuf_PcPowerOffControl msg = DangkangProtobuf_PcPowerOffControl_init_zero;

	if(mcn_poll(pc_poweroff_request_node))
	{
		mcn_node_clear(pc_poweroff_request_node);

		send_buf[0] = PC_COMM_HEAD;
		send_buf[1] = PC_PWR_STA;
		
		pb_ostream_t stream = pb_ostream_from_buffer(&send_buf[3],sizeof(send_buf));
		msg.request = true;
		
		status = pb_encode(&stream, DangkangProtobuf_PcPowerOffControl_fields, &msg);
		if(!status)
			LOG_E("pc pwr status info failed: %s\n", PB_GET_ERROR(&stream));
		else
		{
			send_buf[2] = stream.bytes_written;
			send_buf[send_buf[2] + 5] = PC_COMM_TAIL;

			crc = cal_crc16(send_buf, send_buf[2] + 3);
			send_buf[send_buf[2] + 3] = (crc & 0xff);
			send_buf[send_buf[2] + 4] = (crc & 0xff00) >> 8;
			rt_device_write(dev, 0, send_buf, send_buf[2] + 6);
		}
	}
}

/******************************PC>>>>>>>>MCU*******************************/

/*
 * PC->MCU 清错设置函数
 *
 * Parameter:
 *   Input:
*		-buf:接收数据缓存区
 *		-size：数据长度
 *   Output:
 * Returns:
 *		-0：正常
 *		-其他：异常
 */
int pc_comm_server_func_clear_error(rt_uint8_t *buf,rt_uint8_t size)
{
	size_t message_len = size;
	bool status = false;
	DangkangProtobuf_ErrorClearControl msg = DangkangProtobuf_ErrorClearControl_init_zero;
	
	pb_istream_t stream = pb_istream_from_buffer(buf,message_len);
	status = pb_decode(&stream,DangkangProtobuf_ErrorClearControl_fields,&msg);
	if(!status)
	{
		LOG_E("Encoding failed:%s,size:%d\n",PB_GET_ERROR(&stream),size);
		return E_PROTO_RECV_ERR;
	}
	else
	{
		if(msg.type_request == DangkangProtobuf_ErrorClearType_ECT_ENABLE)
			mcn_publish(MCN_HUB(mcn_ipc_clear_error), NULL);
		clear_error_flag = true;
	}	
	return E_NO_ERR;
}

/*
 * PC->MCU 底盘驱动器初始化函数
 *
 * Parameter:
 *   Input:
*		-buf:接收数据缓存区
 *		-size：数据长度
 *   Output:
 * Returns:
 *		-0：正常
 *		-其他：异常
 */
int pc_comm_server_func_chassis_init(rt_uint8_t *buf,rt_uint8_t size)
{
	size_t message_len = size;
	rt_uint8_t ret = 0;
	bool status = false;
	DangkangProtobuf_ChassisInitialization msg = DangkangProtobuf_ChassisInitialization_init_zero;
	
	pb_istream_t stream = pb_istream_from_buffer(buf,message_len);
	status = pb_decode(&stream,DangkangProtobuf_ChassisInitialization_fields,&msg);
	if(!status)
	{
		LOG_E("Encoding failed:%s,size:%d\n",PB_GET_ERROR(&stream),size);
		ret = E_PROTO_RECV_ERR;
	}
	else
	{
		ret = chassis_init(env_param.chassis_type,NULL);
		chassis_init_flag = true;
	}
	chassis_init_sta = ret;

	return ret;
}

/*
 * PC->MCU PC电源控制反馈函数
 *
 * Parameter:
 *   Input:
*		-buf:接收数据缓存区
 *		-size：数据长度
 *   Output:
 * Returns:
 *		-0：正常
 *		-其他：异常
 */
int pc_comm_server_func_pc_pwr_ctrl(rt_uint8_t *buf,rt_uint8_t size)
{
	rt_uint8_t ret = 0;
	bool status = false;
	size_t message_len = size;
	DangkangProtobuf_PcPowerOffControl msg = DangkangProtobuf_PcPowerOffControl_init_zero;
	
	pb_istream_t stream = pb_istream_from_buffer(buf,message_len);
	status = pb_decode(&stream,DangkangProtobuf_PcPowerOffControl_fields,&msg);
	if(!status)
	{
		LOG_E("Encoding failed:%s,size:%d\n",PB_GET_ERROR(&stream),size);
		ret = E_PROTO_RECV_ERR;
	}
	else
	{
		mcn_publish(MCN_HUB(pc_pwroff_ack), NULL);
		ret = E_NO_ERR;
	}
	return ret;
}

/*******************************************************************************
 *                                  EOF
 ******************************************************************************/
